JBoss Community Archive (Read Only)

Latest WildFly Documentation

Client Authentication with Elytron Client

Client Authentication with Elytron Client

WildFly Elytron uses the Elytron Client project to enable remote clients to authenticate using Elytron. Elytron Client has the following components:

Component

Description

Authentication Configuration

Contains authentication information such as usernames, passwords, allowed SASL mechanisms, and the security realm to use during digest authentication.

MatchRule

Rule used for deciding which authentication configuration to use.

Authentication Context

Set of rules and authentication configurations to use with a client for establishing a connection.

When a connection is established, the client makes use of an authentication context, which gives rules that match which authentication configuration is used with an outbound connection. For example, you could have a rules that use one authentication configuration when connecting to server1 and another authentication configuration when connecting with server2. The authentication context is comprised of a set of authentication configurations and a set of rules that define how they are selected when establishing a connection. An authentication context can also reference ssl-context and can be matched with rules.

To create a client that uses security information when establishing a connection:

  • Create one or more authentication configurations.

  • Create an authentication context by creating rule and authentication configuration pairs.

  • Create a runnable for establishing your connection.

  • Use your authentication context to run your runnable.

When you establish your connection, Elytron Client will use the set of rules provided by the authentication context to match the correct authentication configuration to use during authentication.

You can use one of the following approaches to use security information when establishing a client connection.

IMPORTANT: When using Elytron Client to make EJB calls, any hard-coded programatic authentication information, such as setting Context.SECURITY_PRINCIPAL in the javax.naming.InitialContext, will override the Elytron Client configuration.

The Configuration File Approach

The configuration file approach involves creating an XML file with your authentication configuration, authentication context, and match rules.

custom-config.xml

<configuration>
    <authentication-client xmlns="urn:elytron:1.0">
        <authentication-rules>
            <rule use-configuration="monitor">
                <match-host name="127.0.0.1" />
            </rule>
            <rule use-configuration="administrator">
                <match-host name="localhost" />
            </rule>
        </authentication-rules>
        <authentication-configurations>
            <configuration name="monitor">
                 <sasl-mechanism-selector selector="DIGEST-MD5"/>
                 <providers>
                     <use-service-loader />
                 </providers>
                 <set-user-name name="monitor" />
                 <credentials>
                     <clear-password password="password1!" />
                 </credentials>
                 <set-mechanism-realm name="ManagementRealm" />
             </configuration>

             <configuration name="administrator">
                 <sasl-mechanism-selector selector="DIGEST-MD5"/>
                 <providers>
                     <use-service-loader />
                 </providers>
                 <set-user-name name="administrator" />
                 <credentials>
                     <clear-password password="password1!" />
                 </credentials>
                 <set-mechanism-realm name="ManagementRealm" />
             </configuration>
        </authentication-configurations>
    </authentication-client>
</configuration>

You can then reference that file in your client's code by setting a system property when running your client.

$ java -Dwildfly.config.url=/path/to/the.xml …..

IMPORTANT: If you use the The Programmatic Approach, it will override any provided configuration files even if the wildfly.config.url system property is set.

When creating rules, you can look for matches on various parameters such as hostname, port, protocol, or username. A full list of options for MatchRule are available in the Javadocs. Rules are evaluated in the order in which they are configured.

Common Rules

Rule

Description

match-domain

Takes a single name attribute specifying the security domain to match against.

match-host

Takes a single name attribute specifying the hostname to match against. For example, the host 127.0.0.1 would match on http://127.0.0.1:9990/my/path.

match-no-userinfo

Matches against URIs with no userinfo.

match-path

Takes a single name attribute specifying the path to match against. For example, the path /my/path/ would match on http://127.0.0.1:9990/my/path.

match-port

Takes a single name attribute specifying the port to match against. For example, the port 9990 would match on http://127.0.0.1:9990/my/path.

match-protocol

Takes a single name attribute specifying the protocol to match against. For example, the protocol http would match on http://127.0.0.1:9990/my/path.

match-purpose

Takes a names attribute specifying the list of purposes to match against.

match-urn

Takes a single name attribute specifying the URN to match against.

match-userinfo

Takes a single name attribute specifying the userinfo to match against.

The Programmatic Approach

The programatic approach configures all the Elytron Client configuration in the client's code:

//create your authentication configuration
AuthenticationConfiguration adminConfig =
    AuthenticationConfiguration.empty()
      .setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("DIGEST-MD5")) 
      .useRealm("ManagementRealm")
      .useName("administrator")
      .usePassword("password1!");

//create your authentication context
AuthenticationContext context = AuthenticationContext.empty();
context = context.with(MatchRule.ALL.matchHost("127.0.0.1"), adminConfig);


//create your runnable for establishing a connection
Runnable runnable =
    new Runnable() {
      public void run() {
        try {
           //Establish your connection and do some work
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    };

//use your authentication context to run your client
context.run(runnable);

When adding configuration details to AuthenticationConfiguration and AuthenticationContext, each method call returns a new instance of that object. For example, if you wanted separate configurations when connecting over different hostnames, you could do the following:

//create your authentication configuration
AuthenticationConfiguration commonConfig =
    AuthenticationConfiguration.empty()
      .setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("DIGEST-MD5")) 
      .useRealm("ManagementRealm");

AuthenticationConfiguration administrator =
    commonConfig
      .useName("administrator")
      .usePassword("password1!");


AuthenticationConfiguration monitor =
    commonConfig
      .useName("monitor")
      .usePassword("password1!");


//create your authentication context
AuthenticationContext context = AuthenticationContext.empty();
context = context.with(MatchRule.ALL.matchHost("127.0.0.1"), administrator);
context = context.with(MatchRule.ALL.matchHost("localhost"), monitor);

Common Rules

Rule

Description

matchLocalSecurityDomain(String name)

This is the same as match-domain in the configuration file approach.

matchNoUser()

This is the same as match-no-user in the configuration file approach.

matchPath(String pathSpec)

This is the same as match-path in the configuration file approach.

matchPort(int port)

This is the same as match-port in the configuration file approach.

matchProtocol(String protoName)

This is the same as match-port in the configuration file approach.

matchPurpose(String purpose)

Create a new rule which is the same as this rule, but also matches the given purpose name.

matchPurposes(String... purposes)

This is the same as match-purpose in the configuration file approach.

matchUrnName(String name)

This is the same as match-urn in the configuration file approach.

matchUser(String userSpec)

This is the same as match-userinfo in the configuration file approach.

Also, instead of starting with an empty authentication configuration, you can start with the current configured one by using captureCurrent().

//create your authentication configuration
AuthenticationConfiguration commonConfig = AuthenticationConfiguration.captureCurrent();

Using captureCurrent() will capture any previously established authentication context and use it as your new base configuration. A authentication context is established once its been activated by calling run(). If captureCurrent() is called and no context is currently active, it will try and use the default authentication if available. You can find more details about this in The Configuration File Approach, The Default Configuration Approach, and Using Elytron Client with Clients Deployed to WildFly sections.

Using AuthenticationConfiguration.EMPTY should only be used as a base to build a configuration on top of and should not be used on its own. It provides a configuration that uses the JVM-wide registered providers and enables anonymous authentication.

When specifying the providers on top of the AuthenticationConfiguration.EMPTY configuration, you can specify a custom list, but most users should use WildFlyElytronProvider() providers.

When creating an authentication context, using the context.with(...) will create a new context that merges the rules and authentication configuration from the current context with the provided rule and authentication configuration. The provided rule and authentication configuration will appear after the ones in the current context.

The Default Configuration Approach

The default configuration approach relies completely on the configuration provided by Elytron Client:

//create your runnable for establishing a connection
Runnable runnable =
    new Runnable() {
      public void run() {
        try {
           //Establish your connection and do some work
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    };

// run runnable directly
runnable.run();

To provide a default configuration, Elytron Client tries to auto-discover a wildfly-config.xml file on the filesystem. It looks in the following locations:

  • Location specified by the wildfly.config.url system property set outside of the client code.

  • The classpath root directory.

  • The META-INF directory on the classpath.

If it does not find one, it will try and use the default wildfly-config.xml provided in the $WILDFLY_HOME/bin/client/jboss-client.jar.

default wildfly-config.xml

<configuration>
  <authentication-client xmlns="urn:elytron:1.0">
    <authentication-rules>
      <rule use-configuration="default" />
    </authentication-rules>
    <authentication-configurations>
      <configuration name="default">
        <sasl-mechanism-selector selector="#ALL" />
        <set-mechanism-properties>
          <property key="wildfly.sasl.local-user.quiet-auth" value="true" />
        </set-mechanism-properties>
        <providers>
            <use-service-loader />
        </providers>
      </configuration>
    </authentication-configurations>
  </authentication-client>
</configuration>

Using Elytron Client with Clients Deployed to WildFly

Clients deployed to WildFly can also make use of Elytron Client. In cases where you have included a wildfly-config.xml with your deployment or the system property has been set, an AuthenticationContext is automatically parsed and created from that file.

To load a configuration file outside of the deployment, you can use the parseAuthenticationClientConfiguration(URI) method. This method will return an AuthentcationContext which you can then use in your client’s code using the The Programmatic Approach.

Additionally, clients will also automatically parse and create an AuthenticationContext from the client configuration provided by the elytron subsystem. The client configuration in the elytron subsystem can also take advantage of other components defined in the elytron subsystem such as credential stores. If client configuration is provided by BOTH the deployment and the elytron subsystem, the elytron subsystem’s configuration is used.

Client configuration using wildfly-config.xml

Prior to WildFly 11, many WildFly client libraries used different configuration strategies. WildFly 11 introduces a new wildfly-config.xml file which unifies all client configuration in a single place. In addition to being able to configure authentication using Elytron as described in the previous section, a wildfly-config.xml file can also be used to:

Configure EJB client connections, global interceptors, and invocation timeout

Schema location: https://github.com/wildfly/jboss-ejb-client/blob/4.0.2.Final/src/main/resources/schema/wildfly-client-ejb_3_0.xsd

Example configuration:

wildfly-config.xml

<configuration>
...
    <jboss-ejb-client xmlns="urn:jboss:wildfly-client-ejb:3.0">
        <invocation-timeout seconds="10"/>
        <connections>
            <connection uri="remote+http://10.20.30.40:8080"/>
        </connections>
        <global-interceptors>
            <interceptor class="org.jboss.example.ExampleInterceptor"/>
        </global-interceptors>
    </jboss-ejb-client>
...
</configuration>

Configure HTTP client

Schema location:https://github.com/wildfly/wildfly-http-client/blob/1.0.2.Final/common/src/main/resources/schema/wildfly-http-client_1_0.xsd

Example configuration:

wildfly-config.xml

<configuration>
...
    <http-client xmlns="urn:wildfly-http-client:1.0">
        <defaults>
            <eagerly-acquire-session value="true" />
            <buffer-pool buffer-size="2000" max-size="10" direct="true" thread-local-size="1" />
        </defaults>
    </http-client>
...
</configuration>

Configure a remoting endpoint

Schema location:https://github.com/jboss-remoting/jboss-remoting/blob/5.0.1.Final/src/main/resources/schema/jboss-remoting_5_0.xsd

Example configuration:

wildfly-config.xml

<configuration>
...
    <endpoint xmlns="urn:jboss-remoting:5.0">
        <connections>
            <connection destination="remote+http://10.20.30.40:8080" read-timeout="50" write-timeout="50" heartbeat-interval="10000"/>
        </connections>
    </endpoint>
...
</configuration>

Configure the default XNIO worker

Schema location:https://github.com/xnio/xnio/blob/3.5.1.Final/api/src/main/resources/schema/xnio_3_5.xsd

Example configuration:

wildfly-config.xml

<configuration>
...
    <worker xmlns="urn:xnio:3.5">
        <io-threads value="10"/>
        <task-keepalive value="100"/>
        <stack-size value="5000"/>
    </worker>
...
</configuration>

Note that WildFly client libraries do have reasonable default configuration. Thus, adding configuration for these clients to wildfly-config.xml isn’t mandatory.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 13:36:37 UTC, last content change 2017-09-19 18:19:29 UTC.